//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __CBASICFILE_H__
#define __CBASICFILE_H__

#include <elasys_server.h>
#include "Winhack.h"
#include <linknode.h>
#include <Aura.h>

extern const wchar_t wszIllegal[];
extern const UInt64 bias64;

class CBasicFile : public IBasicFile, IAbsoluteIO, IFileMonitor, public DLinkNode
{
public:
    CARAPI_(PInterface) Probe(
         /* [in]  */ REIID riid);

    CARAPI_(UInt32) AddRef(void);

    CARAPI_(UInt32) Release(void);

    CARAPI Aggregate(
        /* [in] */ AggrType aggrType,
        /* [in] */ PInterface pObject);

    CARAPI GetDomain(
         /* [out] */ PInterface *ppObj);

    CARAPI Read(
        /* [in] */ Int32 offset,
        /* [in] */ Int32 toRead,
        /* [out] */ MemoryBuf * pBuf);

    CARAPI Write(
        /* [in] */ Int32 offset,
        /* [in] */ const MemoryBuf & ezbBuf,
        /* [out] */ Int32 * pWrite);

    CARAPI GetSize(
        /* [out] */ Int32 * pSize);

    CARAPI SetSize(
        /* [in] */ Int32 size);

    CARAPI GetOptimalBlockSize(
        /* [out] */ Int32 * pSize);

    CARAPI Sync();

    CARAPI GetType(
        /* [out] */ FileType * pType);

    CARAPI GetAccessTime(
        /* [out] */ Int32 * pTime);

    CARAPI SetAccessTime(
        /* [in] */ Int32 time);

    CARAPI GetModificationTime(
        /* [out] */ Int32 * pTime);

    CARAPI SetModificationTime(
        /* [in] */ Int32 time);

    CARAPI GetCreateTime(
        /* [out] */ Int32 * pTime);

    CARAPI CheckAccessMode(
        /* [in] */ FileAccessMode mode);

    CARAPI GetAccessMode(
        /* [out] */ FileAccessMode * pMode);

    CARAPI SetAccessMode(
        /* [in] */ FileAccessMode mode);

    CARAPI GetShareMode(
        /* [out] */ FileShareMode *pMode);

    CARAPI SetShareMode(
        /* [in] */ FileShareMode mode);

    CARAPI AddFileMonitor(
        /* [out] */ IEvent **pEvent);

    CARAPI RemoveFileMonitor(
        /* [in] */ IEvent *pEvent);

public:
    CBasicFile(IBasicDirectory *pParenDir);
    ECode Initialize(WString esFileName, FileShareMode fileShareMode);
    ECode Initialize(WString esFileName, FileAccessMode fileAccessMode, FileShareMode fileShareMode);
    virtual ~CBasicFile();
    wchar_t *GetFileName(void) const;

private:
    ECode GetFileTime();
    void LocalTimeToFileTime(Int32 time, FILETIME *pFt);

private:
    Interlocked     m_cRef;

    wchar_t* m_pFileName;

    Int32 m_CreateTime;
    Int32 m_LastModifyTime;
    Int32 m_LastAccessTime;

    HANDLE m_FileHandle;

    Aura_Handle m_hFileLock;
    Aura_Handle m_hParentFileListLock;

    FileShareMode m_FileShareMode;
    FileAccessMode m_FileAccessMode;

    IBasicDirectory *m_pParentDir;
};

#endif
